#pragma once
#include"Common.hpp"

//这个类里面维护了一张自由链表，负责申请空间、释放空间
//我们上层申请释放空间都是在这张自由链表当中申请的
class ThreadCache
{
public:
    ThreadCache(){}
    //按字节为单位申请内存的接口
    void* AllocMemory(size_t size);
    //归还内存的接口
    //obj是要释放的空间的起始地址，size是空间的大小，单位是字节
    void RecycleMemory(void*obj,size_t size);

    //如果ThreadCache没有空间了，则需要从Central Cache获取空间
    void*GetSpaceFromCentral(size_t size,size_t index);

     //当链表太长时，将自由链表的节点交给中心缓存
    void TruncRangeList(FreeList&freelist,size_t num);
    ~ThreadCache(){}
private:
    FreeList _freelist[MAX_BUCKET];  //这是一个hash桶结构，下面挂着一个个的自由链表节点
};

//对于当前层的hash桶而言，我们需要考虑映射的方法，而内存池是为了提高访问内存的效率
//所以我们需要在兼顾效率的同时，节省内存空间，即内存内碎片的问题，所以我们要做到按需分配内存
//为了达到按需分配内存空间，我们需要对这个hash桶进行切分
//由于自由链表下面挂了从操作系统当中提前申请好的并且被切分的大块内存，所以为了解决内碎片的问题
//我们需要对这个hash桶(也就是数组)进行空间划分，划分的依据就是内存块的大小
//即：我们需要将不同大小的内存块按照它的大小，挂在不同的hash桶当中
//那么我们需要划分多少个不同大小的桶呢？
//答案是208个桶，划分方式如下：
// 整体控制在最多10%左右的内碎片浪费
// [1,128]					8byte对齐	    freelist[0,16)
// [128+1,1024]				16byte对齐	    freelist[16,72)
// [1024+1,8*1024]			128byte对齐	    freelist[72,128)
// [8*1024+1,64*1024]		1024byte对齐     freelist[128,184)
// [64*1024+1,256*1024]		8*1024byte对齐   freelist[184,208)
//观察上面的划分规则，我们可以看到，1-128字节的空间按照8字节对齐，我们需要划分16个桶，
//即：第一个桶下面的内存块大小是8字节，第二个桶下面的内存块大小是16个字节，以此类推，最大到第十六个桶，下面挂的内存块大小是128字节
//而划分到128字节是是在第16个桶当中，所以八字节对齐一共要划分16个位的数组，即16个桶
//129-1024字节的空间是按照16字节对齐，一共要划分56个位的数组，即56个桶
//1025-8*1024字节的空间按照128字节对齐，一共要划分56个位的数组，即56个桶
//8*1024+1-64*1024字节的空间按照1024字节对齐，一共要划分56个位的数组，即56个桶
//以此类推，一共要划分16+56+56+56+24=209个桶，所以包含自由链表的数组的长度是208